package controls {
	
	import mx.binding.utils.ChangeWatcher;
	
	import mx.containers.Form;
	import mx.containers.FormItem;
	import mx.core.IFactory;
	import mx.core.UIComponent;
	import mx.validators.Validator;
	
	import org.siam.core.data.editors.IEditorContext;
	import org.siam.core.schemas.ISchemaManager;
	
	public class FormExample extends Form {
		
		public function FormExample() {
		}

		[Bindable]
		public var dataProvider:Object;
		
		public function configure(schemaManager:ISchemaManager):void {
			// clear children
			this.removeAllChildren();
			
			// iterate thru each schema properties
			for each (var propertyId:String in schemaManager.propertyIds) {
				
				// create and validate editor
				var editorContext:IEditorContext = schemaManager.findEditor(propertyId);
				var dataField:String = editorContext.dataField;
				var editor:UIComponent = editorContext.factory.newInstance();
				editor.width = 150;
				// create validator and assign to editor
				var validatorFactory:IFactory = schemaManager.findValidator(propertyId).factory;
				var validator:Validator = validatorFactory.newInstance();
				validator.source = editor;
				validator.property = dataField;
				// create form item and attach editor
				var item:FormItem = new FormItem();
				item.label = schemaManager.findMetadata("name", propertyId);
				item.addChild(editor);
				this.addChild(item);
				
				// setup data bindings between dataProvider and editor
				setupBindings(editor, validator, dataField, propertyId);
			}
		}

		private function setupBindings(editor:UIComponent, validator:Validator, dataField:String, propertyId:String):void {
			// listen to dataProvider changes -> update editor
			ChangeWatcher.watch(this, "dataProvider", function(event:Event):void {
				editor[dataField] = dataProvider ? dataProvider[propertyId] : null;
			}, true);
			// listen to editor changes -> update dataProvider
			ChangeWatcher.watch(editor, dataField, function(event:Event):void {
				if (dataProvider) {
					var newValue:Object = editor[dataField];
					var oldValue:Object = dataProvider[propertyId];
					if (newValue != oldValue) {
					 	dataProvider[propertyId] = newValue;
					}
				}
			}, true);
		}
	}
}